home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / s0ftpj / udp_spoof_detect.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-17  |  6.8 KB  |  292 lines

  1. /*
  2.  * DETECT UDP SP00FiNG ON OUR FREEBSD BOX VIA KLD
  3.  * ----------------------------------------------
  4.  *
  5.  * This is a partial porting of my linux lkm to detect spoofing from our box..
  6.  * to another system....
  7.  *
  8.  * This kld detects only UDP Spoofing. Other implementations are possible
  9.  * changing pru_send function of the protocol you are interested in... You
  10.  * can use this kld to understand how to do that on another protocol or you 
  11.  * can write me for other implementations.
  12.  * 
  13.  * Set MY_IP, MY_SECOND_IP with your address/es...
  14.  * 
  15.  * This kld modifies a function of udp pr_usrreqs structure... other **bsd
  16.  * systems have a function to interface socket routines with protocols.
  17.  * 
  18.  * Notes: TCP implementation is possible via kld
  19.  *      IGMP & ICMP are also possible but they use pru_send in common
  20.  *      so check inp->inp_ip_p for IPPROTO_IGMP, IPPROTO_ICMP and so
  21.  *      on...
  22.  * 
  23.  * idea & code by pIGpEN [pigpen@s0ftpj.org, deadhead@sikurezza.org]
  24.  *
  25.  * s0ftpr0ject - digital security for y2k
  26.  * www.s0ftpj.org
  27.  *
  28.  * sikurezza.org - italian security mailing list
  29.  * www.sikurezza.org
  30.  *
  31.  */
  32.  
  33. /* 
  34.  * pay attention: this code is compatible only with new kernels with
  35.  * for example jail support... so you have to change pru_send to have
  36.  * it working on old versions.
  37.  * 
  38.  * uname -a
  39.  *
  40.  * FreeBSD storpio.cameretta.pig 4.0-19990705-CURRENT FreeBSD 4.0-19990705-
  41.  * CURRENT #4 ..... i386
  42.  *
  43.  * If you wanna a porting of this code and you have no time to do that 
  44.  * write to me at: deadhead@sikurezza.org with subject "PORTING A KLD"
  45.  * 
  46.  */
  47.  
  48. #define MY_IP         "192.168.1.2"
  49. #define MY_SECOND_IP    "192.168.1.2"
  50. /* my machine has only an ip address and no other eth# or ip aliases */
  51. #define LOOPBACK    "127.0.0.1"
  52. #define DONT_PASS
  53.  
  54. #include <sys/param.h>
  55. #include <sys/systm.h>
  56. #include <sys/malloc.h>
  57. #include <sys/mbuf.h>
  58. #include <sys/kernel.h>
  59. #include <sys/proc.h>
  60. #include <sys/socket.h>
  61. #include <sys/socketvar.h>
  62. #include <sys/sysctl.h>
  63. #include <sys/syslog.h>
  64. #include <sys/protosw.h>
  65. #include <net/if.h>
  66. #include <net/route.h>
  67. #include <netinet/in.h>
  68. #include <netinet/in_systm.h>
  69. #include <netinet/in_pcb.h>
  70. #include <netinet/ip.h>
  71. #include <netinet/ip_var.h>
  72. #include <netinet/ip_icmp.h>
  73. #include <netinet/udp.h>
  74. #include <netinet/udp_var.h>
  75.  
  76.  
  77. extern struct     protosw     inetsw[];
  78. extern struct     udpstat     udpstat;
  79. static int     udpcksum    =    1;
  80.  
  81.  
  82. static int       s_load             __P((struct module *, int, void *));
  83.  
  84. static int     udp_send        __P((struct socket * , int , 
  85.                          struct mbuf *, struct sockaddr *, 
  86.                          struct mbuf *, struct proc *));
  87.  
  88. static int     (*old_udp_send)    __P((struct socket * , int ,
  89.                          struct mbuf *, struct sockaddr *,
  90.                          struct mbuf *, struct proc *));
  91.  
  92. static int     udp_output        __P((struct inpcb    *, struct mbuf *,
  93.                          struct sockaddr *, struct mbuf *,
  94.                          struct proc *));
  95.  
  96. static u_int32_t inaton            __P((const char *));
  97.  
  98.  
  99. /* ipfw macro... inet_ntoa() also works well from here it's the same thing */
  100.  
  101. #define print_ip(a)    printf("%d.%d.%d.%d",                \
  102.                 (int)(ntohl(a.s_addr)  >> 24) & 0xFF,    \
  103.                 (int)(ntohl(a.s_addr)  >> 16) & 0xFF,    \
  104.                 (int)(ntohl(a.s_addr)  >> 8 ) & 0xFF,    \
  105.                 (int)(ntohl(a.s_addr))  & 0xFF);
  106.  
  107. static int
  108. s_load (struct module *module, int cmd, void *arg)
  109. {
  110.  int s;
  111.  
  112.  switch(cmd) {
  113.     case MOD_LOAD:
  114.       s = splnet();
  115.       old_udp_send = inetsw[ip_protox[IPPROTO_UDP]].pr_usrreqs->pru_send;
  116.       inetsw[ip_protox[IPPROTO_UDP]].pr_usrreqs->pru_send = udp_send;
  117.       splx(s);
  118.       break;
  119.             
  120.     case MOD_UNLOAD:
  121.       s = splnet();
  122.       inetsw[ip_protox[IPPROTO_UDP]].pr_usrreqs->pru_send = old_udp_send;
  123.       splx(s);
  124.       break;
  125.  }
  126.  
  127.  return 0;
  128. }
  129.  
  130. static moduledata_t s_mod_1 = {
  131.             "udp_mod",
  132.             s_load,
  133.             0
  134. };
  135.  
  136. DECLARE_MODULE(udp_mod, s_mod_1, SI_SUB_PSEUDO, SI_ORDER_ANY);
  137.  
  138.  
  139. static int
  140. udp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
  141.         struct mbuf *control, struct proc *p)
  142. {
  143.     struct inpcb *inp;
  144.  
  145.     inp = sotoinpcb(so);
  146.     if (inp == 0) {
  147.         m_freem(m);
  148.         return EINVAL;
  149.     }
  150.     return udp_output(inp, m, addr, control, p);
  151. }
  152.  
  153.  
  154. static int
  155. udp_output(inp, m, addr, control, p)
  156.     register struct inpcb *inp;
  157.     register struct mbuf *m;
  158.     struct sockaddr *addr;
  159.     struct mbuf *control;
  160.     struct proc *p;
  161. {
  162.     register struct udpiphdr *ui;
  163.     register int len = m->m_pkthdr.len;
  164.     struct in_addr laddr;
  165.     struct sockaddr_in *sin;
  166.     int s = 0, error = 0;
  167.  
  168.     if (control)
  169.         m_freem(control);        /* XXX */
  170.  
  171.     if (len + sizeof(struct udpiphdr) > IP_MAXPACKET) {
  172.         error = EMSGSIZE;
  173.         goto release;
  174.     }
  175.  
  176.     if (addr) {
  177.         sin = (struct sockaddr_in *)addr;
  178.         prison_remote_ip(p, 0, &sin->sin_addr.s_addr);
  179.         laddr = inp->inp_laddr;
  180.         if (inp->inp_faddr.s_addr != INADDR_ANY) {
  181.             error = EISCONN;
  182.             goto release;
  183.         }
  184.         /*
  185.          * Must block input while temporarily connected.
  186.          */
  187.         s = splnet();
  188.         error = in_pcbconnect(inp, addr, p);
  189.         if (error) {
  190.             splx(s);
  191.             goto release;
  192.         }
  193.     } else {
  194.         if (inp->inp_faddr.s_addr == INADDR_ANY) {
  195.             error = ENOTCONN;
  196.             goto release;
  197.         }
  198.     }
  199.     /*
  200.      * Calculate data length and get a mbuf
  201.      * for UDP and IP headers.
  202.      */
  203.     M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
  204.     if (m == 0) {
  205.         error = ENOBUFS;
  206.         if (addr)
  207.             splx(s);
  208.         goto release;
  209.     }
  210.  
  211.     /*
  212.      * Fill in mbuf with extended UDP header
  213.      * and addresses and length put into network format.
  214.      */
  215.     ui = mtod(m, struct udpiphdr *);
  216.     bzero(ui->ui_x1, sizeof(ui->ui_x1));
  217.     ui->ui_pr = IPPROTO_UDP;
  218.     ui->ui_len = htons((u_short)len + sizeof (struct udphdr));
  219.     ui->ui_src = inp->inp_laddr;
  220.     ui->ui_dst = inp->inp_faddr;
  221.     ui->ui_sport = inp->inp_lport;
  222.     ui->ui_dport = inp->inp_fport;
  223.     ui->ui_ulen = ui->ui_len;
  224.  
  225.     /*
  226.      * Stuff checksum and output datagram.
  227.      */
  228.     ui->ui_sum = 0;
  229.     if (udpcksum) {
  230.         if ((ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) + len)) == 0)
  231.         ui->ui_sum = 0xffff;
  232.     }
  233.     ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
  234.     ((struct ip *)ui)->ip_ttl = inp->inp_ip_ttl;    /* XXX */
  235.     ((struct ip *)ui)->ip_tos = inp->inp_ip_tos;    /* XXX */
  236.  
  237.     if(ui->ui_src.s_addr != inaton(MY_IP)         && 
  238.        ui->ui_src.s_addr != inaton(MY_SECOND_IP)     && 
  239.        ui->ui_src.s_addr != inaton(LOOPBACK)) {
  240.      printf("UDP Spoofing detected as: "); 
  241.      print_ip(ui->ui_src);
  242.      printf(" to ");
  243.      print_ip(ui->ui_dst);
  244. #ifdef DONT_PASS        
  245.      printf(" Packet not accepted to be sent\n");
  246.      goto release;
  247. #endif
  248.     }
  249.     
  250.     udpstat.udps_opackets++;
  251.     
  252.     error = ip_output(m, inp->inp_options, &inp->inp_route,
  253.         inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST),
  254.         inp->inp_moptions);
  255.  
  256.     if (addr) {
  257.         in_pcbdisconnect(inp);
  258.         inp->inp_laddr = laddr;    /* XXX rehash? */
  259.         splx(s);
  260.     }
  261.     return (error);
  262.  
  263. release:
  264.     m_freem(m);
  265.     return (error);
  266. }
  267.  
  268. u_int32_t inaton(const char *str)
  269. {
  270.     unsigned long l;
  271.     unsigned int val;
  272.     int i;
  273.  
  274.     l = 0;
  275.  
  276.     for(i=0; i < 4; i++) {
  277.         l <<= 8;
  278.         if(*str != '\0') {
  279.             val = 0;
  280.             while(*str != '\0' && *str != '.') {
  281.                 val *= 10;
  282.                 val += *str - '0';
  283.                 str++;
  284.             }
  285.             l |= val;
  286.             if(*str != '\0')
  287.                 str++;
  288.         }
  289.     }
  290.     return(htonl(l));
  291. }
  292.